{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Licensed to the Apache Software Foundation (ASF) under one\n",
    "or more contributor license agreements.  See the NOTICE file\n",
    "distributed with this work for additional information\n",
    "regarding copyright ownership.  The ASF licenses this file\n",
    "to you under the Apache License, Version 2.0 (the\n",
    "\"License\"); you may not use this file except in compliance\n",
    "with the License.  You may obtain a copy of the License at\n",
    "\n",
    "  http://www.apache.org/licenses/LICENSE-2.0\n",
    "\n",
    "Unless required by applicable law or agreed to in writing,\n",
    "software distributed under the License is distributed on an\n",
    "\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n",
    "KIND, either express or implied.  See the License for the\n",
    "specific language governing permissions and limitations\n",
    "under the License."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Experiments with Sparse Labeling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import math\n",
    "import json\n",
    "\n",
    "import scipy as sp\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import sklearn\n",
    "\n",
    "import torch\n",
    "\n",
    "import ucr\n",
    "import scikit_wrappers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.simplefilter(action='ignore', category=FutureWarning)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# GPU number\n",
    "gpu = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch._C.Generator at 0x7f72f966c230>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.random.seed(0)\n",
    "torch.manual_seed(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "path = 'Data/UCR' # Path to datasets\n",
    "dataset = 'TwoPatterns'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "train, train_labels, test, test_labels = ucr.load_UCR_dataset(path, dataset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f72db1a4c18>]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(test[0, 0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Loading the encoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_path = '' # Folder containing the saved model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "classifier = scikit_wrappers.CausalCNNEncoderClassifier()\n",
    "hf = open(\n",
    "    os.path.join(\n",
    "        model_path, dataset + '_hyperparameters.json'\n",
    "    ), 'r'\n",
    ")\n",
    "hp_dict = json.load(hf)\n",
    "hf.close()\n",
    "hp_dict['cuda'] = True\n",
    "hp_dict['gpu'] = gpu\n",
    "classifier.set_params(**hp_dict)\n",
    "classifier.load(os.path.join(model_path, dataset ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.99975"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Original classifier score\n",
    "classifier.score(test, test_labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sparse Labeling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Tested number of labels\n",
    "nb_labels_list = [int(12 * pow(1.25, i)) for i in range(20)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Precompute the frozen representations for efficiency puproses\n",
    "train_features = classifier.encode(train)\n",
    "test_features = classifier.encode(test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12 0.7198 0.07630930480616373\n",
      "15 0.8053500000000001 0.04000018749956055\n",
      "18 0.7750999999999999 0.03526102664415773\n",
      "23 0.8804500000000001 0.035383400062741266\n",
      "29 0.8980499999999999 0.041716123981022035\n",
      "36 0.9004999999999999 0.037496666518505375\n",
      "45 0.9417 0.021591317699482814\n",
      "57 0.9599500000000001 0.020026482466973566\n",
      "71 0.9794499999999999 0.011272089424769514\n",
      "89 0.9849500000000001 0.004945705207551294\n",
      "111 0.99215 0.005582562135793905\n",
      "139 0.9944000000000001 0.0038065732621348613\n",
      "174 0.99695 0.0008717797887081673\n",
      "218 0.99825 0.0009486832980504971\n",
      "272 0.99885 0.0005385164807134529\n",
      "341 0.9986499999999999 0.0007176350047203738\n",
      "426 0.9992500000000002 0.0003162277660168558\n",
      "532 0.9993500000000001 0.0004636809247747796\n",
      "666 0.9996 0.00030000000000001873\n",
      "832 0.9998000000000001 0.00018708286933867647\n"
     ]
    }
   ],
   "source": [
    "# Learns an SVM for each 5 different splits for each tested number of labels\n",
    "for nb_labels in nb_labels_list:\n",
    "    results = []\n",
    "    for i in range(5):\n",
    "        split = sklearn.model_selection.train_test_split(\n",
    "            train_features, train_labels, train_size=nb_labels, stratify=train_labels\n",
    "        )\n",
    "        classifier.fit_classifier(split[0], split[2])\n",
    "        results.append(classifier.classifier.score(test_features, test_labels))\n",
    "    print(nb_labels, np.mean(results), np.std(results))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1000 0.99975 0.0\n"
     ]
    }
   ],
   "source": [
    "# Case where no label is missing\n",
    "results = []\n",
    "for i in range(5):\n",
    "    classifier.fit_classifier(train_features, train_labels)\n",
    "    results.append(classifier.classifier.score(test_features, test_labels))\n",
    "print(np.shape(train_features)[0], np.mean(results), np.std(results))"
   ]
  }
 ],
 "metadata": {
  "file_extension": ".py",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "mimetype": "text/x-python",
  "name": "python",
  "npconvert_exporter": "python",
  "pygments_lexer": "ipython3",
  "version": 3
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
